package cn.dapeng.future;

import java.util.concurrent.*;

public class CompletableFutureTest {

    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        // CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "hello");
//        CompletableFuture<String> future = new CompletableFuture<>();
//        process(future);
//        System.out.println(future.get());


        long startTime = System.currentTimeMillis();
        //p2();
        //p3();
        //p4();
        //p5();
        p6();
        System.out.println("耗时：" + (System.currentTimeMillis() - startTime));

        System.in.read();
    }


    public static void process(CompletableFuture<String> future) {
        future.complete("hello");
    }


    public static void p2() {
        CompletableFuture.supplyAsync(() -> "hello")
                .thenAccept(t -> System.out.println("haha:" + t));
    }

    public static void p3() {
        CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> {
            sleep(3);
            return "Hello";
        });

        CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> {
            sleep(3);
            return " World!";
        });

        CompletableFuture<String> futureC = futureA.thenCombine(futureB, (resultA, resultB) -> resultA + resultB);

        try {
            System.out.println(futureC.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    public static void p4() {
        CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> {
            sleep(3);
            System.out.println("current-thread name:" + Thread.currentThread().getName());
            return "Hello";
        });

        CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> {
            sleep(3);
            System.out.println("current-thread name:" + Thread.currentThread().getName());
            return " World!";
        });

        futureA.runAfterEither(futureB, () -> System.out.println("over!")).join();

    }

    public static void p5() {
        CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> {
            sleep(3);
            System.out.println("current-thread name:" + Thread.currentThread().getName());
            return "Hello";
        });

        CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> {
            sleep(3);
            System.out.println("current-thread name:" + Thread.currentThread().getName());
            return " World!";
        });

        CompletableFuture.allOf(futureA, futureB).join();

    }

    public static void p6() {
        CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> {
            sleep(3);
            System.out.println("current-thread name:" + Thread.currentThread().getName());
            return "Hello";
        });

        CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> {
            sleep(3);
            System.out.println("current-thread name:" + Thread.currentThread().getName());
            return " World!";
        });

        CompletableFuture<String> futureC = futureA.thenCombine(futureB, (resultA, resultB) -> resultA + resultB);

        // 任务执行的结果，  正常执行 存在result中 如果有异常 存在err中
//        futureC.whenComplete((result, err) -> {
//            System.out.println(result);
//            System.out.println(err);
//        });
        futureC.exceptionally(e -> {
            System.out.println(e.getMessage());
            return null;
        });
    }

    public static void sleep(long timeout) {
        try {
            TimeUnit.SECONDS.sleep(timeout);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

}
